Sparsetodense

将稀疏张量转换为密集张量。该算子根据稀疏索引和值,将稀疏元素填充到密集张量的对应位置。支持标量值模式(所有位置使用相同的值)和向量值模式(每个索引对应不同的值)。

对于每个稀疏元素,根据其索引计算在密集张量中的线性位置,根据 is_scalar 标志,将对应的稀疏值写入密集张量的对应位置

\[\begin{split}\text{output}[\text{index}] = \begin{cases} \text{sparse\_values}[0], & \text{if } \text{is\_scalar} = 1 \\ \text{sparse\_values}[i], & \text{if } \text{is\_scalar} = 0 \end{cases}\end{split}\]
输入:
  • indices_vec - 稀疏张量的索引数组,大小为 sparse_length * 4,每4个连续的int值表示一个稀疏元素在4维密集张量中的位置坐标 [dim0, dim1, dim2, dim3]

  • sparse_values - 稀疏张量的值数组。如果 is_scalar = 1,只需要 sparse_values[0] 有效;如果 is_scalar = 0,需要 sparse_length 个值。

  • output_strides - 输出密集张量的步长数组,大小为4,用于将多维索引转换为线性索引。output_strides[0], output_strides[1], output_strides[2] 对应前3维的步长,第4维的步长为1。

  • sparse_length - 稀疏张量中非零元素的数量。

  • is_scalar - 是否为标量值标志。1 表示所有稀疏元素使用相同的值(sparse_values[0]),0 表示每个索引对应不同的值。

  • core_mask - 核掩码(仅共享存储版本需要)。

输出:
  • output - 输出密集张量的数据数组。输出数组的大小由 output_strides 和最大索引值确定。未在 indices_vec 中指定的位置保持原值(调用前需要初始化)。

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持fp32, int8, int16, int32, fp64, cplx64, cplx128

  • MT7004 支持fp16, fp32, int16, int32, cplx64

共享存储版本:

void i8_sparsetodense_s(int *indices_vec, int8_t *sparse_values, int8_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void i16_sparsetodense_s(int *indices_vec, int16_t *sparse_values, int16_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void i32_sparsetodense_s(int *indices_vec, int32_t *sparse_values, int32_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void hp_sparsetodense_s(int *indices_vec, half *sparse_values, half *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void fp_sparsetodense_s(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void dp_sparsetodense_s(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void c64_sparsetodense_s(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)
void c128_sparsetodense_s(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

C调用示例(向量值模式):

 1//FT78NE示例
 2#include <stdio.h>
 3#include <sparsetodense.h>
 4
 5int main(int argc, char* argv[]) {
 6    // 假设在DDR空间
 7    // 输出密集张量形状 [2, 3, 4, 5]
 8    int output_shape[] = {2, 3, 4, 5};
 9
10    // 计算步长:stride0 = 3*4*5 = 60, stride1 = 4*5 = 20, stride2 = 5, stride3 = 1
11    int output_strides[4];
12    output_strides[0] = 3 * 4 * 5;  // 60
13    output_strides[1] = 4 * 5;      // 20
14    output_strides[2] = 5;          // 5
15    output_strides[3] = 1;          // 第4维步长为1(未使用)
16
17    // 稀疏元素:3个非零元素
18    int sparse_length = 3;
19
20    // 索引:[[0,0,0,0], [0,1,2,3], [1,2,3,4]]
21    int *indices_vec = (int *)0xA0000000;
22    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;  // 位置(0,0,0,0)
23    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;  // 位置(0,1,2,3)
24    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4; // 位置(1,2,3,4)
25
26    // 稀疏值:每个索引对应不同的值
27    float *sparse_values = (float *)0xA1000000;
28    sparse_values[0] = 1.0f;
29    sparse_values[1] = 2.0f;
30    sparse_values[2] = 3.0f;
31
32    // 输出密集张量(需要预先初始化为0或默认值)
33    float *output = (float *)0xB0000000;
34    int output_size = 2 * 3 * 4 * 5;  // 120
35    memset(output, 0, output_size * sizeof(float));
36
37    int is_scalar = 0;  // 向量值模式
38    int core_mask = 0xff;
39
40    fp_sparsetodense_s(indices_vec, sparse_values, output, output_strides,
41                      sparse_length, is_scalar, core_mask);
42
43    return 0;
44}

C调用示例(标量值模式):

 1//FT78NE示例
 2#include <stdio.h>
 3#include <sparsetodense.h>
 4
 5int main(int argc, char* argv[]) {
 6    // 假设在DDR空间
 7    int output_strides[4];
 8    output_strides[0] = 3 * 4 * 5;  // 60
 9    output_strides[1] = 4 * 5;       // 20
10    output_strides[2] = 5;           // 5
11    output_strides[3] = 1;
12
13    int sparse_length = 3;
14
15    // 索引:[[0,0,0,0], [0,1,2,3], [1,2,3,4]]
16    int *indices_vec = (int *)0xA0000000;
17    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;
18    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;
19    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4;
20
21    // 所有位置使用相同的值
22    float *sparse_values = (float *)0xA1000000;
23    sparse_values[0] = 5.0f;  // 只有这个值会被使用
24
25    float *output = (float *)0xB0000000;
26    int output_size = 2 * 3 * 4 * 5;
27    memset(output, 0, output_size * sizeof(float));
28
29    int is_scalar = 1;  // 标量值模式
30    int core_mask = 0xff;
31
32    fp_sparsetodense_s(indices_vec, sparse_values, output, output_strides,
33                      sparse_length, is_scalar, core_mask);
34
35    return 0;
36}

私有存储版本:

void i8_sparsetodense_p(int *indices_vec, int8_t *sparse_values, int8_t *output, int *output_strides, int sparse_length, int is_scalar)
void i16_sparsetodense_p(int *indices_vec, int16_t *sparse_values, int16_t *output, int *output_strides, int sparse_length, int is_scalar)
void i32_sparsetodense_p(int *indices_vec, int32_t *sparse_values, int32_t *output, int *output_strides, int sparse_length, int is_scalar)
void hp_sparsetodense_p(int *indices_vec, half *sparse_values, half *output, int *output_strides, int sparse_length, int is_scalar)
void fp_sparsetodense_p(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar)
void dp_sparsetodense_p(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar)
void c64_sparsetodense_p(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar)
void c128_sparsetodense_p(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar)

C调用示例(私有存储版本):

 1//FT78NE示例
 2#include <stdio.h>
 3#include <sparsetodense.h>
 4
 5int main(int argc, char* argv[]) {
 6    // 假设在L2空间
 7    int output_strides[4];
 8    output_strides[0] = 3 * 4 * 5;  // 60
 9    output_strides[1] = 4 * 5;      // 20
10    output_strides[2] = 5;          // 5
11    output_strides[3] = 1;
12
13    int sparse_length = 3;
14
15    int *indices_vec = (int *)0x10000000;
16    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;
17    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;
18    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4;
19
20    float *sparse_values = (float *)0x10001000;
21    sparse_values[0] = 1.0f;
22    sparse_values[1] = 2.0f;
23    sparse_values[2] = 3.0f;
24
25    float *output = (float *)0x10002000;
26    int output_size = 2 * 3 * 4 * 5;
27    memset(output, 0, output_size * sizeof(float));
28
29    int is_scalar = 0;
30
31    fp_sparsetodense_p(indices_vec, sparse_values, output, output_strides,
32                      sparse_length, is_scalar);
33
34    return 0;
35}